/****************************************************************************
	This file is part of Basqet.

	Basqet is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	Basqet is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
    along with Basqet.  If not, see <http://www.gnu.org/licenses/>.

****************************************************************************/

#include "notedata.h"

#include "xmlstrings.h"

#include "basketdescriptor.h"
#include "basketcontent.h"

#include <QString>
#include <QDateTime>

#include <QtXml>
#include <QtDebug>

/***************************************************************************/

NoteData::NoteData(BasketDescriptor* container, BasketContent* pContent)
		:mBasket(container), mBasketContent(pContent)
{
}

void NoteData::setup(QDomElement tag)
{
	mXML = tag;
	// Check the Note-ID-tag
	if (0 == mXML.elementsByTagName(XML_NOTE_NOTEID).count())
	{
		QString noteID = QDateTime::currentDateTime().toString("yyyy-MM-dd_hhmmsszz");
		mNoteID = mXML.ownerDocument().createElement(XML_NOTE_NOTEID);
		QDomCDATASection noteIDSection = mNoteID.ownerDocument().createCDATASection(noteID);

		mXML.appendChild(mNoteID);
		mNoteID.appendChild(noteIDSection);

	}
	else
	{
		mNoteID = mXML.firstChildElement(XML_NOTE_NOTEID);
	}


	QDomElement	size;

	if (0 == mXML.elementsByTagName(XML_NOTE_SIZE).count())
	{
		size = mXML.ownerDocument().createElement(XML_NOTE_SIZE);
		mXML.appendChild(size);

		mWidth  = size.ownerDocument().createAttribute(XML_NOTE_SIZE_WIDTH);
		mHeight = size.ownerDocument().createAttribute(XML_NOTE_SIZE_HEIGHT);

		size.setAttributeNode(mWidth);
		size.setAttributeNode(mHeight);

	}
	else
	{
		size = mXML.firstChildElement(XML_NOTE_SIZE);
	}

	mWidth  = size.attributeNode(XML_NOTE_SIZE_WIDTH);
	mHeight = size.attributeNode(XML_NOTE_SIZE_HEIGHT);

	QDomElement	pos;

	if (0 == mXML.elementsByTagName(XML_NOTE_POS).count())
	{
		pos = mXML.ownerDocument().createElement(XML_NOTE_POS);
		mXML.appendChild(pos);

		qDebug() << "pos is null:" << pos.isNull();

		mPosX = pos.ownerDocument().createAttribute(XML_NOTE_POS_X);
		mPosY = pos.ownerDocument().createAttribute(XML_NOTE_POS_Y);

		pos.setAttributeNode(mPosX);
		pos.setAttributeNode(mPosY);

	}
	else
	{

		pos = mXML.elementsByTagName(XML_NOTE_POS).at(0).toElement();
	}

	mPosX  = pos.attributeNode(XML_NOTE_POS_X);
	mPosY = pos.attributeNode(XML_NOTE_POS_Y);

	// Check the Tag-List-tag
	if (0 == mXML.elementsByTagName(XML_NOTE_TAGLIST).count())
	{
		mTagList = mXML.ownerDocument().createElement(XML_NOTE_TAGLIST);
		QDomCDATASection tagListCDATA = mTagList.ownerDocument().createCDATASection("");

		mXML.appendChild(mTagList);
		mTagList.appendChild(tagListCDATA);

	}
	else
	{
		mTagList = mXML.firstChildElement(XML_NOTE_TAGLIST);
	}


}

void NoteData::copyFrom(const NoteData* other)
{
	if (other)
	{

		this->mBasketContent = other->mBasketContent;
		setNoteID(other->mNoteID.firstChild().toCDATASection().nodeValue());
		setGeometry(other->getPosition(), other->getSize());

	}
}

void NoteData::getContents(QMap<QString, QVariant>& contents)
{
	contents.insert("noteId", QVariant(getNoteID()));
	contents.insert("pos", QVariant(getPosition()));
	contents.insert("size", QVariant(getSize()));

}


void NoteData::setContents(const QMap<QString, QVariant>& content)
{
	setNoteID(content["noteId"].toString());
	setGeometry(content["pos"].toPoint(), content["size"].toSize());
}



QDomElement	NoteData::getObjectNode()
{
	return mXML;
}

BasketContent* NoteData::getBasketContent() const
{
	return mBasketContent.data();
}

BasketDescriptor* NoteData::getBasketDescriptor() const
{
	return mBasket.data();
}


bool NoteData::removeNote()
{
	QDomNode	parent = mXML.parentNode();
	mXML = parent.removeChild(mXML).toElement();

	emit removed();

	return !mXML.isNull();

}

void NoteData::setGeometry(QPoint pos, QSize size)
{
	QString convert;


	if (size.isValid())
	{
		mWidth.setValue(convert.setNum(size.width()));

		mHeight.setValue(convert.setNum(size.height()));
	}

	if (!pos.isNull())
	{

		mPosX.setValue(convert.setNum(pos.x()));
		mPosY.setValue(convert.setNum(pos.y()));
	}

	emit geometryChanged(pos, size);

}


/** To be implemented by subclases that needs this **/
void NoteData::save()
{

}

QSize  NoteData::getSize() const
{
	int width  = mWidth.value().toInt();
	int height = mHeight.value().toInt();

	return QSize(width, height);

}

QPoint NoteData::getPosition() const
{
	int x = mPosX.value().toInt();
	int y = mPosY.value().toInt();

	return QPoint(x,y);
}

void NoteData::setNoteID(QString noteId)
{
	mNoteID.firstChild().toCDATASection().setNodeValue(noteId);

}

QString NoteData::getNoteID()
{
	return mNoteID.firstChild().toCDATASection().nodeValue();

}

QStringList NoteData::getTagList() const
{
	QStringList tagList;

	tagList = mTagList.firstChild().toCDATASection().nodeValue().split("#", QString::SkipEmptyParts);

	return tagList;

}

void NoteData::setTagList(QStringList tagList)
{
	mTagList.firstChild().toCDATASection().setData(tagList.join("#"));
}


QString	NoteData::getTagBySameFamily(QString tag)
{
	QStringList tagList = getTagList();

	QStringList families = tag.split("-");

	if (families.size() >= 1)
	{
		QString tagFamily = families[0];

		QStringList items = tagList.filter(QString("%1-").arg(tagFamily));

		if (items.size() > 0)
			return items[0];

	}

	return QString();

}

void NoteData::clearTagValue(QString tag)
{
	QStringList tagList = getTagList();

	if (tagList.contains(tag))
	{
		tagList.removeAll(tag);
		emit tagCleared(tag);

		setTagList(tagList);
	}


}

bool NoteData::hasTag(QString tag)
{
	QStringList tagList = getTagList();

	return tagList.contains(tag);
}


void NoteData::setTagValue(QString tag)
{
	QStringList tagList = getTagList();

	if (!tagList.contains(tag))
	{
		tagList.append(tag);
		emit tagSet(tag);

		setTagList(tagList);
	}

}



void NoteData::replaceTag(QString oldTag, QString newTag)
{
	QStringList tagList = getTagList();

	if (tagList.contains(oldTag))
		tagList.removeAll(oldTag);

	if (!tagList.contains(newTag))
		tagList.append(newTag);


	emit tagChanged(oldTag, newTag);

	setTagList(tagList);

}




